// // 云函数入口文件
const cloud = require('wx-server-sdk')

const axios = require('axios');

const DAY_NUMBER = ['日', '一', '二', '三', '四', '五', '六']

cloud.init()
const db = cloud.database();

const holiday = db.collection('holiday')
/**
 * 获取+8时区的日期对象
 * @param {Date} date 日期
 */
function getRealDate(date) {
    if (date.getTimezoneOffset() == 0) {
        return new Date(date.getTime() + (8 * 60 * 60 * 1000))
    }
    return date;
}
/**
 * 获取参数中小时和分钟的日期
 * @param {Number} hour 小时
 * @param {Number} minute 分钟
 * @param {Date} date 日期对象
 */
function getHourDate(hour, minute, date = new Date()) {
    // const [hour, minute] = hm.split(":");
    date = getRealDate(date)
    return new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), hour, minute) - (8 * 60 * 60 * 1000));
}
/**
 * 返回的统一格式
 */
function Message(code = 1, msg = '', data = {}) {
    return {
        code,
        msg,
        data
    };
}

// 云函数入口函数
exports.main = async (event, context) => {
    const wxContext = cloud.getWXContext()
    switch (event.action) {
        case 'getWorkingDay':
            return getWorkingDay(event);
        case "getFreeDay":
            return getFreeDay(event);
    }
    return {
        event,
        openid: wxContext.OPENID,
        appid: wxContext.APPID,
        unionid: wxContext.UNIONID,
    }
}
/**
 * 获取最近一周的工作日
 * @param lastTime 小时分钟字符串 当前未超过该时间则把今日计入返回数据中
 */
async function getWorkingDay(event) {
    let {
        lastTime
    } = event;
    const dates = [];
    let res = getLastTimeDate(lastTime);
    let {
        code,
        data
    } = res;
    if (code == 1) {
        dates.push(data);
    } else if (code != 2) {
        return res;
    }
    for (let i = 1; i <= 7; i++) {
        let date = new Date();
        date.setDate(date.getDate() + i);
        dates.push(date)
    }
    let workDates = [];
    for (let i = 0; i < dates.length; i++) {
        let date = dates[i];
        let dateStr = dateFormat("YYYY-mm-dd", getRealDate(date));
        //从数据库获取该日是否是工作的状态码
        const {
            data
        } = await holiday.where({
            date: dateStr
        }).get()
        let status;
        //如果没有状态码 则从外部接口获取 
        if (data.length == 0) {
            let result = await axios.get("http://tool.bitefu.net/jiari/", {
                params: {
                    d: dateStr
                }
            })
            status = result.data;
            //获取后记录下来 便于多次获取
            //本来想写缓存 可惜云开发没缓存可写
            holiday.add({
                data: {
                    date: dateStr,
                    status,
                }
            })
        } else {
            status = data[0].status;
        }
        if (status == 0) {
            workDates.push(date);
        }
    }
    return Message(1, "", workDates.map(item => formatDate(item)));
}
/**
 * 获取一周中星期的某一天数组的格式化日期
 * @param week 一周Day数组
 * @param lastTime 小时分钟字符串
 */
async function getFreeDay(event) {
    const {
        week,
        lastTime
    } = event;
    const dates = [];
    let res = getLastTimeDate(lastTime);
    let {
        code,
        data
    } = res;
    if (code == 1) {
        dates.push(formatDate(data));
    } else if (code != 2) {
        return res;
    }
    if (!week || !Array.isArray(week) || week.length == 0) {
        return Message(-54)
    }
    let date = getRealDate(new Date());

    for (let i = 0; i < 7; i++) {
        date.setDate(date.getDate() + 1);
        if (week.includes(date.getDay())) {
            dates.push(formatDate(date, true));
        }
    }
    return Message(1, "", dates);
}
/**
 * 格式化返回的日期
 * @param {Date} date 日期对象
 * @param {Boolean} isReal 是否是时区+8的日期
 */
function formatDate(date, isReal) {
    date = isReal ? date : getRealDate(date);
    return {
        date: date.getMonth() + 1 + "-" + date.getDate(),
        day: "星期" + DAY_NUMBER[date.getDay()],
        year: date.getFullYear(),
    }
}
/**
 * 格式化日期对象 返回格式化字符串
 * @param {string} fmt 日期格式
 * @param {Date} date 日期对象
 */
function dateFormat(fmt, date) {
    let ret;
    const opt = {
        "Y+": date.getFullYear().toString(), // 年
        "m+": (date.getMonth() + 1).toString(), // 月
        "d+": date.getDate().toString(), // 日
        "H+": date.getHours().toString(), // 时
        "M+": date.getMinutes().toString(), // 分
        "S+": date.getSeconds().toString() // 秒
        // 有其他格式化字符需求可以继续添加，必须转化成字符串
    };
    for (let k in opt) {
        ret = new RegExp("(" + k + ")").exec(fmt);
        if (ret) {
            fmt = fmt.replace(ret[1], (ret[1].length == 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, "0")))
        };
    };
    return fmt;
}
/**
 * 校验小时分钟字符串 并返回日期对象
 * @param  lastTime 小时分钟
 * @return {Message} data：当日Date
 */
function getLastTimeDate(lastTime) {
    if (lastTime) {
        laseTime = lastTime.split(":");
        if (laseTime.length != 2) {
            return Message("-51");
        }
        let [hour, minute] = laseTime;
        if (isNaN(hour) || isNaN(minute)) {
            return Message("-52");
        }
        hour = parseInt(hour);
        minute = parseInt(minute);
        if (hour < 0 || hour > 23 || minute < 0 || minute > 59) {
            return Message("-53");
        }
        let date = getHourDate(hour, minute);
        if (date.getTime() > Date.now()) {
            return Message("1", "", date);
        }
    }
    return Message("2");
}